#include<iostream>
#include<vector>
#include<memory>
using std::endl;
using std::cout;
using std::vector;
using std::allocator;

#include <memory>

template<typename T>
class Vector {
public:
    Vector() : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr) {}
    
    ~Vector() {
        if (_start) {
            for (T* p = _finish; p != _start; --p) {
                _alloc.destroy(p - 1);
            }
            _alloc.deallocate(_start, _end_of_storage - _start);
        }
    }
    
    void push_back(const T& value) {
        if (_finish == _end_of_storage) {
            reallocate();
        }
        _alloc.construct(_finish, value);
        ++_finish;
    }
    
    void pop_back() {
        if (_finish != _start) {
            --_finish;
            _alloc.destroy(_finish);
        }
    }
    
    int size() const {
        return _finish - _start;
    }
    
    int capacity() const {
        return _end_of_storage - _start;
    }
    
private:
    void reallocate() {
        size_t new_capacity = size() == 0 ? 1 : 2 * size();
        T* new_start = _alloc.allocate(new_capacity);
        T* new_finish = new_start;
        T* old_ptr = _start;
        
        while (old_ptr != _finish) {
            _alloc.construct(new_finish, std::move(*old_ptr));
            ++new_finish;
            ++old_ptr;
        }
        
        if (_start) {
            while (old_ptr != _start) {
                _alloc.destroy(--old_ptr);
            }
            _alloc.deallocate(_start, _end_of_storage - _start);
        }
        
        _start = new_start;
        _finish = new_finish;
        _end_of_storage = _start + new_capacity;
    }

private:
    static std::allocator<T> _alloc;
    T* _start;
    T* _finish;
    T* _end_of_storage;
};

template<typename T>
std::allocator<T> Vector<T>::_alloc;

int test(){
    Vector<int> test;
    test.push_back(1);
    test.push_back(2);
    cout<< test.capacity()<<endl;
}

int main(void){
    test();
}